home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Pascal / Snippets / DevilAbout / DevilAbout.p < prev    next >
Encoding:
Text File  |  1995-12-04  |  15.7 KB  |  589 lines  |  [TEXT/MPPS]

  1. {-----------------------------------------------------------------
  2.  
  3. This is an AboutBox program for the Devil in a Blue Dress group map
  4. project for Marathon.
  5.  
  6. This application demonstrates scrolling movie credits with asynchronous
  7. sound playing.  To build the FAT application, first build the 68K application,
  8. then build the PPC application and it will automatically be FAT.
  9.  
  10. The technique for scrolling the text was taken from Metrowerks CodeWarrior
  11. About application.
  12.  
  13. Project includes:
  14.  
  15. DevilAbout.p        Source code
  16. DevilAboutSA.µ       68k project
  17. SADevilFAT.µ        PPC project
  18. DevilAbout.µ.rsrc    Main resources
  19.  
  20. Date:  11/20/95
  21. Programmed by Bill Catambay, catambay@aol.com
  22. -----------------------------------------------------------------}
  23.  
  24. PROGRAM AboutBox;
  25.  
  26.  
  27. USES 
  28.     QuickDraw, Fonts, Events, Windows, TextEdit, Dialogs, Types, Qdoffscreen, Sound,
  29.     TextEdit, ToolUtils, Resources, Processes;
  30.  
  31. Const
  32.     FadeLevels = 12;
  33.     aboutSound = 1240;
  34.     endSound = 128;
  35.     kDiscovery = 10001;
  36.     kTreachery = 10008;
  37.     kShowdown = 10014;
  38.     kRetribution = 10018;
  39.     kFinal = 10100;
  40.     TEXTCredits = 128;
  41.  
  42. Type
  43.     AnimateState = (animateWaiting, animateActive, animateDone);
  44.     CreditsRec = record
  45.         theGWorldP: GWorldPtr;
  46.         viewRect: Rect;
  47.         pictRect: Rect;
  48.         pictHeight: integer;
  49.         end;
  50.  
  51. Var
  52.     Picts: array[1..5] of integer;
  53.     pictRefnum: integer;
  54.     pictNum: integer;
  55.     noPicts: boolean;
  56.     sndRefnum: integer;
  57.     PixelDepth: integer;
  58.     speed: integer;
  59.     centerFrame: Rect;
  60.     aboutBoxWindow: WindowPtr;
  61.     drawWorld: GWorldPtr;
  62.     backWorld: GWorldPtr;
  63.     curWorld: GworldPtr;
  64.     loopWorld: GworldPtr;
  65.     looprect: rect;
  66.     saveGW: GWorldPtr;
  67.     saveGD: GDHandle;
  68.     err: OSErr;
  69.     event: EventRecord;
  70.     exitSignal: boolean;
  71.     gotEvent: boolean;
  72.     theCreditsRec: CreditsRec;
  73.     theSoundChannelP: SndChannelPtr;
  74.     theSoundH, endsoundH: Handle;
  75.        SndChanStat: SCStatus;
  76.        loopSound: boolean;
  77.     animCreditsFade: AnimateState;
  78.     animCreditsScroll: AnimateState;
  79.     fadeColor: RGBColor;
  80.     grayIndex: integer;
  81.     grayLevels: ARRAY[0..FadeLevels-1] OF integer;
  82.     ticks: longint;
  83.     startTicks: longint;
  84.     endTicks: longint;
  85.     waitTicks: longint;
  86.     i,j: integer;
  87.     fontnum: integer;
  88.     creditsWidth: integer;
  89.     creditsBox: Rect;
  90.     offScreen: boolean;
  91.     
  92. Procedure DisplayWarning(strID: integer);
  93.  
  94. Var
  95.     Warningstr:        stringHandle;
  96.     dummy:            integer;
  97.     
  98.     begin
  99.     WarningStr := GetString(strID);
  100.     if WarningStr = NIL then
  101.         ParamText('Unknown error occurred','','','')
  102.     else
  103.         ParamText(WarningStr^^,'','','');
  104.     dummy := Alert(128,NIL);
  105.     end; { of displayWarning }
  106.             
  107. Function CenterRect(crect:        rect;
  108.                     mainrect:    rect): rect;
  109.  
  110. Var
  111.     prect:    rect;
  112.     
  113.     begin
  114.     prect.top := (mainrect.bottom - mainrect.top - (crect.bottom -
  115.         crect.top)) div 2 + mainrect.top;
  116.     prect.bottom := prect.top + (crect.bottom - crect.top);
  117.     prect.left := (mainrect.right - mainrect.left - (crect.right -
  118.         crect.left)) div 2 + mainrect.left;
  119.     prect.right := prect.left + (crect.right - crect.left);
  120.     CenterRect := prect;
  121.     end; { of centerPict }
  122.     
  123. Procedure GoMainscreen;
  124.  
  125.     begin
  126.     SetGWorld(saveGW,saveGD);
  127.     UnlockPixels(curWorld^.portPixMap);
  128.     offScreen := FALSE;
  129.     end;
  130.     
  131. Procedure GoOffscreen(var offWorld:    GworldPtr);
  132.  
  133.     begin
  134.     GetGworld(saveGW,saveGD);
  135.     if not lockPixels(offWorld^.portPixMap) then;
  136.     SetGWorld(offWorld,NIL);
  137.     curWorld := offWorld;
  138.     offScreen := TRUE;
  139.     end;
  140.     
  141. Procedure SetCreditView;
  142.  
  143. Var
  144.     offset: integer;
  145.     textid: integer;
  146.     outGWorldP: GWorldPtr;
  147.     theText: Handle;
  148.     theTE: TEHandle;
  149.     theStyle: StScrpHandle;
  150.         
  151.     begin
  152.     DisposeGWorld(drawWorld);
  153.     case picts[pictNum] of
  154.     kDiscovery,
  155.     kShowdown,
  156.     kRetribution:    offset := 0;
  157.     kTreachery:        offset := 350;
  158.     kFinal:            offset := 100;
  159.     {CASE}            end;
  160.     if noPicts then
  161.         offset := 200;
  162.     with theCreditsRec.viewRect do
  163.         begin
  164.         right := aboutBoxWindow^.portRect.right - 20 - offset;
  165.         left := right - 250;
  166.         top := aboutBoxWindow^.portRect.top + 170;
  167.         bottom := top + 160;
  168.         end;
  169.     if NoErr <> NewGWorld(drawWorld, PixelDepth, theCreditsRec.viewRect, NIL, NIL, 0) then
  170.         ExitToShell;
  171.     creditsBox := theCreditsRec.viewRect;
  172.     if theCreditsRec.theGWorldP <> NIL then
  173.         begin
  174.         DisposeGWorld(theCreditsRec.theGWorldP);
  175.         theCreditsRec.theGWorldP := NIL;
  176.         end;
  177.     textid := TEXTCredits + pictNum - 1;
  178.     { Put Text in a TERecord. }
  179.     theTE := TEStyleNew(CreditsBox, CreditsBox);
  180.     theText := GetResource('TEXT', textid);
  181.     theStyle := StScrpHandle(GetResource('styl', textid));
  182.     HLock(theText);
  183.     HidePen;
  184.     TEStyleInsert(theText^, GetHandleSize(theText), theStyle, theTE);
  185.     ShowPen;
  186.     HUnLock(theText);
  187.     ReleaseResource(theText);
  188.     if theStyle <> NIL then
  189.         ReleaseResource(Handle(theStyle));
  190.     TESetAlignment(teJustCenter, theTE);
  191.     TECalText(theTE);
  192.     { Determine height of the Text. }
  193.     CreditsBox.right := CreditsBox.right - CreditsBox.left;
  194.     CreditsBox.left := 0;
  195.     CreditsBox.top := 0;
  196.     CreditsBox.bottom := TEGetHeight(theTE^^.nLines, 0, theTE);
  197.     { Create new GWorld that is the height of the Text. }
  198.     err := NewGWorld(outGWorldP, pixelDepth, CreditsBox, NIL,
  199.                      GetGWorldDevice(drawWorld), noNewDevice);
  200.     GoOffscreen(outGWorldP);                
  201.     EraseRect(CreditsBox);
  202.     { Draw Text inside GWorld. }
  203.     theTE^^.viewRect := CreditsBox;
  204.     theTE^^.destRect := CreditsBox;
  205.     theTE^^.inPort := GrafPtr(outGWorldP);
  206.     TEUpdate(CreditsBox, theTE);
  207.     TEDispose(theTE);
  208.     InvertRect(CreditsBox);            { White letters on black background }
  209.     GoMainScreen;
  210.     theCreditsRec.theGWorldP := outGWorldP;
  211.     theCreditsRec.pictRect.left := 0;
  212.     theCreditsRec.pictRect.top := 0;
  213.     theCreditsRec.pictRect.right := theCreditsRec.viewRect.right - theCreditsRec.viewRect.left;
  214.     theCreditsRec.pictRect.bottom := theCreditsRec.viewRect.bottom - theCreditsRec.viewRect.top;
  215.     theCreditsRec.pictHeight := creditsBox.bottom;
  216.     end;
  217.     
  218. Procedure UpdateLoopWorld;
  219.  
  220.     begin
  221.     if loopWorld = NIL then
  222.         exit(updateLoopWorld);
  223.     GoOffscreen(loopWorld);
  224.     CopyBits(GrafPtr(aboutBoxWindow)^.portBits, GrafPtr(loopWorld)^.portBits,
  225.         loopRect, loopWorld^.portRect, srcCopy, NIL);
  226.     GoMainscreen;
  227.     if loopSound then
  228.         begin
  229.         setport(aboutBoxWindow);
  230.         textsize(10);
  231.         foreColor(yellowColor);
  232.         moveto(looprect.left, looprect.top - 4 + (looprect.bottom - looprect.top + 1) div 2);
  233.         DrawString('Continuous Play');
  234.         foreColor(blackColor);
  235.         end;
  236.     end; { of updateLoopWorld }
  237.     
  238. Procedure NewPict;
  239.  
  240. Var
  241.     thePicture: PicHandle;
  242.     reset: boolean;
  243.  
  244.     begin
  245.     if picts[pictNum] = kTreachery then
  246.         reset := true;
  247.     pictNum := 1 + (pictNum mod 5);
  248.     if picts[pictNum] = kTreachery then
  249.         reset := true;
  250.     SetCreditView;
  251.     UseResFile(pictRefnum);
  252.     if noPicts then
  253.         thePicture := GetPicture(picts[1])
  254.     else
  255.         thePicture := GetPicture(picts[pictNum]);
  256.     UseResFile(curResFile);
  257.     if thePicture = NIL then
  258.         begin
  259.         displayWarning(129);
  260.         noPicts := true;
  261.         UseResFile(pictRefnum);
  262.         thePicture := GetPicture(picts[1]);
  263.         UseResFile(curResFile);
  264.         SetCreditView;
  265.         end;
  266.     if thePicture = NIL then
  267.         ExitToShell;
  268.     GoOffscreen(backWorld);
  269.     drawPicture(thePicture, backWorld^.portRect);
  270.     GoMainscreen;
  271.     ReleaseResource(handle(thePicture));
  272.     CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits, 
  273.         backWorld^.portRect, backWorld^.portRect, srcCopy, NIL);
  274.     updateLoopWorld;
  275.     err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
  276.     end;
  277.     
  278. Function CheckCurrent: boolean;
  279.  
  280. Var
  281.     i:    integer;
  282.     thePicture: PicHandle;
  283.     
  284.     begin
  285.     checkCurrent := false;
  286.     for i := 2 to 5 do
  287.         begin
  288.         thePicture := GetPicture(picts[i]);
  289.         if thePicture = NIL then
  290.             begin
  291.             checkCurrent := true;
  292.             exit(checkCurrent);
  293.             end;
  294.         ReleaseResource(handle(thePicture));
  295.         end;
  296.     end; { of checkCurrent }
  297.     
  298. Procedure SetUpGraphics;
  299.  
  300. Var
  301.     thePicture: PicHandle;
  302.     picFrame: Rect;
  303.  
  304.     begin
  305.     picts[1] := kDiscovery;
  306.     picts[2] := kTreachery;
  307.     picts[3] := kShowdown;
  308.     picts[4] := kRetribution;
  309.     picts[5] := kFinal;
  310.     sndRefnum := OpenResFile('Sounds');
  311.     if sndRefnum = -1 then
  312.         sndRefnum := curResFile;
  313.     pictRefnum := OpenResFile('Shapes');
  314.     if pictRefnum = -1 then
  315.         pictRefnum := OpenResFile('Devil Installer');
  316.     noPicts := pictRefnum = -1;
  317.     if noPicts then
  318.         begin
  319.         pictRefnum := curResFile;
  320.         noPicts := checkCurrent;
  321.         end;
  322.     if noPicts then
  323.         displayWarning(128);
  324.     UseResFile(pictRefnum);
  325.     GetFNum('Monaco', fontnum);
  326.     PixelDepth := 16;
  327.     offScreen := false;
  328.     loopSound := false;
  329.     pictNum := 1;
  330.     thePicture := GetPicture(picts[pictNum]);
  331.     UseResFile(curResFile);
  332.     if thePicture = NIL then
  333.         ExitToShell;
  334.     startTicks := TickCount;
  335.     picFrame := thePicture^^.picFrame;
  336.     centerFrame := centerRect(picFrame,qd.screenBits.bounds);
  337.     aboutBoxWindow := NewCWindow(NIL,centerFrame,'', TRUE, plainDBox,pointer(-1), FALSE, 0);
  338.     if NoErr <> NewGWorld(backWorld, PixelDepth, picFrame, NIL, NIL, 0) then
  339.         ExitToShell;
  340.     GoOffscreen(backWorld);
  341.     drawPicture(thePicture, picFrame);
  342.     GoMainscreen;
  343.     ReleaseResource(handle(thePicture));
  344.     CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits, 
  345.         picFrame, picFrame, srcCopy, NIL);
  346.     startTicks := TickCount - startTicks;
  347.     speed := (startTicks - 23) div 18;
  348.     if speed < 1 then
  349.         speed := 1
  350.     else if speed > 7 then
  351.         speed := 7;
  352.     end;
  353.  
  354. Function Num2Str (num: integer): string;
  355.  
  356. Var
  357.     str: str255;
  358.  
  359.     begin
  360.     NumToString(num, str);
  361.     Num2Str := str;
  362.     end; { of Num2Str }
  363.  
  364. Procedure UpdateStatus;
  365.  
  366. Var
  367.     ch:    char;
  368.     
  369.     begin
  370.     ch := CHR(BAnd(Event.message, charCodeMask));
  371.     case ch of
  372.     chr(30):    inc(speed);
  373.     chr(31):    dec(speed);
  374.     chr(28):    begin
  375.                 pictNum := 3 + (pictNum mod 5);
  376.                 newPict;
  377.                 end;
  378.     chr(29):    newPict;
  379.     'l','L':    begin
  380.                 if loopWorld = NIL then
  381.                     begin
  382.                     setRect(loopRect,0,0,90,25);
  383.                     if NoErr <> NewGWorld(loopWorld, PixelDepth, looprect, NIL, NIL, 0) then
  384.                         ExitToShell;
  385.                     offsetRect(loopRect,10,aboutBoxWindow^.portRect.bottom - 22);
  386.                     end;
  387.                 loopSound := not loopSound;
  388.                 if not loopSound then
  389.                     CopyBits(GrafPtr(loopWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
  390.                         loopWorld^.portRect, loopRect, srcCopy, NIL)
  391.                 else
  392.                     UpdateLoopWorld;
  393.                 end;
  394.     {CASE}        end;
  395.     if speed = 0 then
  396.         speed := 1;
  397.     end; { of updateStatus }
  398.     
  399. Function CheckSound: boolean;
  400.  
  401. Var
  402.     sndOn: boolean;
  403.     
  404.     begin
  405.     if theSoundChannelP <> NIL then
  406.         begin
  407.         Err := SndChannelStatus(theSoundChannelP, sizeof(SndChanStat), @SndChanStat);
  408.         if Err = NoErr then
  409.             sndOn := SndChanStat.scChannelBusy
  410.         else
  411.             sndOn := false;
  412.         end;
  413.     checkSound := sndOn;
  414.     end;
  415.     
  416. BEGIN
  417. InitGraf(@qd.thePort);
  418. InitFonts;
  419. InitWindows;
  420. InitMenus;
  421. TEInit;
  422. InitDialogs(NIL);
  423. InitCursor;
  424. MaxApplZone;
  425. MoreMasters;
  426. SetUpGraphics;
  427. theSoundChannelP := NIL;
  428. theSoundH := NIL;
  429. endSoundH := NIL;
  430. grayLevels[0] := 4369;
  431. grayLevels[1] := 8738;
  432. grayLevels[2] := 17476;
  433. grayLevels[3] := 21845;
  434. grayLevels[4] := 30583;
  435. grayLevels[5] := -30584;
  436. grayLevels[6] := -21846;
  437. grayLevels[7] := -17477;
  438. grayLevels[8] := -13108;
  439. grayLevels[9] := -8557;
  440. grayLevels[10] := -4370;
  441. grayLevels[11] := -1;
  442. theCreditsRec.theGWorldP := NIL;
  443. SetCreditView;
  444. UseResFile(sndRefNum);
  445. theSoundH := GetResource('snd ', aboutSound);
  446. endSoundH := GetResource('snd ', endSound);
  447. UseResFile(curResFile);
  448. HLockHi(theSoundH);
  449. if theSoundH <> NIL then
  450.     begin
  451.     err := SndNewChannel(theSoundChannelP, sampledSynth, initMono, NIL);
  452.     if err = noErr then
  453.         err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
  454.     end;
  455. FlushEvents(everyEvent,0);
  456. exitSignal := false;
  457. animCreditsFade := animateActive;
  458. animCreditsScroll := animateWaiting;
  459. grayIndex := 0;
  460. repeat
  461.     if loopSound & (not CheckSound) then
  462.         err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
  463.     startTicks := TickCount;
  464.     gotEvent := WaitNextEvent(mDownMask + keyDownMask + osMask,event,1,NIL);
  465.     if gotEvent & (event.what = keyDown) then
  466.         updateStatus;
  467.     if gotEvent & (event.what = mouseDown) then
  468.         exitSignal := true;
  469.     if gotEvent & (event.what = osEvt) then 
  470.         if band(brotl(event.message,8),$FF) = suspendResumeMessage then
  471.             if BAnd(event.message,resumeFlag) = 0 then
  472.                 exitSignal := true;
  473.     if (animCreditsFade = animateActive) and
  474.         (grayIndex >= FadeLevels) then
  475.         begin
  476.         animCreditsFade := animateDone;
  477.         Delay(30, ticks);
  478.         animCreditsScroll := animateActive;
  479.         end;
  480.     if (animCreditsScroll = animateActive) and
  481.         (theCreditsRec.pictRect.top > theCreditsRec.pictHeight) then
  482.         begin
  483.         theCreditsRec.pictRect.top := 1;
  484.         theCreditsRec.pictRect.bottom := theCreditsRec.viewRect.bottom - 
  485.                                          theCreditsRec.viewRect.top + 1;
  486.         end;
  487.     if animCreditsFade = animateActive then
  488.         begin
  489.         Delay(3, ticks);
  490.         GoOffScreen(drawWorld);
  491.         CopyBits(GrafPtr(theCreditsRec.theGWorldP)^.portBits, GrafPtr(drawWorld)^.portBits,
  492.                 theCreditsRec.pictRect, theCreditsRec.viewRect, srcCopy, NIL);
  493.         fadeColor.red := grayLevels[grayIndex];
  494.         fadeColor.blue := grayLevels[grayIndex];
  495.         fadeColor.green := grayLevels[grayIndex];
  496.         grayIndex := grayIndex + 1;
  497.         RGBForeColor(fadeColor);
  498.         PenMode(adMin);
  499.         PaintRect(theCreditsRec.viewRect);
  500.         PenMode(patCopy);
  501.         ForeColor(blackColor);
  502.         CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(drawWorld)^.portBits,
  503.                  theCreditsRec.viewRect, theCreditsRec.viewRect, adMax, NIL);
  504.         GoMainScreen;
  505.         CopyBits(GrafPtr(drawWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
  506.                  theCreditsRec.viewRect, theCreditsRec.viewRect, srcCopy, NIL);
  507.         end;
  508.     if animCreditsScroll = animateActive then
  509.         begin
  510.         creditsWidth := theCreditsRec.viewRect.right -
  511.             theCreditsRec.viewRect.left - 1;
  512.         GoOffScreen(drawWorld);
  513.         theCreditsRec.pictRect.top := theCreditsRec.pictRect.top + speed;
  514.         theCreditsRec.pictRect.bottom := theCreditsRec.pictRect.bottom + speed;
  515.         if theCreditsRec.pictRect.bottom <= theCreditsRec.pictHeight then
  516.             CopyBits(GrafPtr(theCreditsRec.theGWorldP)^.portBits, GrafPtr(drawWorld)^.portBits,
  517.                      theCreditsRec.pictRect, theCreditsRec.viewRect, srcCopy, NIL) 
  518.         else
  519.             begin
  520.             GoMainScreen;
  521.             animCreditsScroll := animateDone;
  522.             cycle;
  523.             end;
  524.         PenMode(adMin);    { Fade out at top and fade in at bottom. }
  525.         j := FadeLevels - 1;
  526.         For i := 0 TO j - 1 do
  527.             begin
  528.             fadeColor.red := grayLevels[i];
  529.             fadeColor.blue := grayLevels[i];
  530.             fadeColor.green := grayLevels[i];
  531.             RGBForeColor(fadeColor);
  532.             MoveTo(theCreditsRec.viewRect.left, theCreditsRec.viewRect.top + i);
  533.             Line(creditsWidth, 0);
  534.             MoveTo(theCreditsRec.viewRect.left, theCreditsRec.viewRect.bottom - i - 1);
  535.             Line(creditsWidth, 0);
  536.             end;
  537.         ForeColor(blackColor);
  538.         PenMode(patCopy);
  539.         CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(drawWorld)^.portBits,
  540.                   theCreditsRec.viewRect, theCreditsRec.viewRect, adMax, NIL);
  541.         GoMainScreen;
  542.         CopyBits(GrafPtr(drawWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
  543.                   theCreditsRec.viewRect, theCreditsRec.viewRect, srcCopy, NIL);
  544.          end;
  545.      if animCreditsScroll = animateDone then
  546.          begin
  547.         if pictNum = 5 then
  548.             begin
  549.             animCreditsScroll := animateWaiting;
  550.             WaitTicks := TickCount;
  551.             err := SndPlay(theSoundChannelP, SndListHandle(endSoundH), true);
  552.             end
  553.         else
  554.             begin
  555.             animCreditsScroll := animateActive;
  556.             NewPict;
  557.             end;
  558.         end;
  559.      if (animCreditsScroll = animateWaiting) and
  560.         (animCreditsFade = animateDone) then
  561.          if WaitTicks + 180 <= TickCount then
  562.              begin
  563.             animCreditsFade := animateActive;
  564.             grayIndex := 0;
  565.              NewPict;
  566.              end;
  567.      EndTicks := TickCount; 
  568.      if endTicks = startTicks then 
  569.          while endTicks = TickCount do;  { Just in case the CPU is _that_ fast }
  570. until exitSignal;
  571. FlushEvents(Bor(mDownMask, Bor(mUpMask, Bor(keyDownMask, Bor(keyUpMask,autoKeyMask)))),0);
  572. if theCreditsRec.theGWorldP <> NIL then
  573.     DisposeGWorld(theCreditsRec.theGWorldP);
  574. if loopWorld <> NIL then
  575.     DisposeGWorld(loopWorld);
  576. HUnlock(theSoundH);
  577. HUnlock(endSoundH);
  578. if theSoundChannelP <> NIL then
  579.     err := SndDisposeChannel(theSoundChannelP, true);
  580. if theSoundH <> NIL then
  581.     ReleaseResource(theSoundH);
  582. if endSoundH <> NIL then
  583.     ReleaseResource(endSoundH);
  584. DisposeGWorld(drawWorld);
  585. DisposeGWorld(backWorld);
  586. DisposeWindow(WindowPtr(aboutBoxWindow));
  587. PurgeMem(maxSize);
  588. END.
  589.